/**
 * @function 获取小数的小数点后数字的长度。
 * @param number {number} 小数
 * @return {number} 小数点后长度（如：0.123 返回 3）
 */
function getDecimalPrecision(number) {
    try {
        return number.toString().split(".")[1].length;
    } catch (e) {
        return 0;
    }
}

/**
 * @function 比较一组小数小数点后的长度。
 * @param numbers {Array} 要比较的小数数组。
 * @return {number} 返回小数点后最长的长度。
 */
function getMaxLength(numbers) {
    let length = 0;
    for (let i = 0; i < numbers.length; i++) {
        let temporary = getDecimalPrecision(numbers[i]);
        length = length > temporary ? length : temporary;
    }
    return length;
}

/**
 * @function 将小数转化为指定长度的整数。
 * @param number {number} 需要转化的小数。
 * @param length {number} 小数点后的长度，相当于将小数乘以 10 的 length 次幂。
 * @returns {number}
 */
function decimalToInteger(number, length) {
    let self_length = getDecimalPrecision(number);
    if (self_length === 0) {
        return number * Math.pow(10, length);
    } else {
        let integer = number.toString().replace(".", "");
        integer = integer.charAt(0) === "0" ? integer.slice(1, integer.length) : integer;
        return parseInt(integer + "0".repeat(length - self_length));
    }
}

/**
 * @function 将浮点数转换为整数再相加以得到较为精确的结果。
 * @param number1
 * @param number2
 * @return {number}
 */
function addition(number1, number2) {
    let length = getMaxLength([number1, number2]);
    let result = decimalToInteger(number1, length) + decimalToInteger(number2, length);
    return result / Math.pow(10, length);
}


/**
 * @function 将浮点数转换为整数再相除以得到较为精确的结果。
 * @param number1
 * @param number2
 * @return {number}
 */
function division(number1, number2) {
    let length = getMaxLength([number1, number2]);
    return decimalToInteger(number1, length) / decimalToInteger(number2, length);
}

/**
 * @function 将浮点数转换为整数再相乘以得到较为精确的结果。
 * @return {number}
 * @param number1
 * @param number2
 */
function multiplication(number1, number2) {
    let length = getMaxLength([number1, number2]);
    let result = decimalToInteger(number1, length) * decimalToInteger(number2, length);
    return result / Math.pow(10, length * 2);
}

/*************************************************************************/
/**
 * @function 创建点
 * @param x {number} 横坐标
 * @param y {number} 纵坐标
 * @return {{x, y}}
 */
function creatPoint(x, y) {
    return {
        x: x,
        y: y
    }
}

/**
 * @function 设置一个矩形范围，返回左上角坐标：(x1,y1)，右下角坐标：(x2, y2)。
 * @param x {number} 矩形左上角 X 坐标。
 * @param y {number} 矩形左上角 Y 坐标。
 * @param width {number} 矩形的宽。
 * @param height {number} 矩形的高。
 * @return {{y1, x1, y2: *, x2: *}}
 */
function setRestricted(x, y, width, height) {
    return {
        x1: x,
        y1: y,
        x2: x + width,
        y2: y + height
    };
}

/**
 * @function 取得几个某范围内的不重复随机整数（包括最小值和最大值）。
 * @param min {number} 最小数字
 * @param max {number} 最大数字
 * @param count {number} 想取得的随机数的个数。
 * @return {[]}
 */
function setRandomNumber(min, max, count) {
    if (max - min <= count) {
        let array = [];
        for (let i = 0; i < count; i++) {
            let x = Math.floor(Math.random() * (max+1) + min);
            while (array.includes(x)) {
                x = Math.floor(Math.random() * (max+1) + min);
            }
            array.push(x);
        }
        return array;
    }
}

/**
 * @function 直线公式已知 x 求 y，两点式：(y-y2)/(y1-y2) = (x-x2)/(x1-x2)
 * @param point1 {{x:number,y:number}} 点 1 坐标：(x, y)
 * @param point2 {{x:number,y:number}} 点 2 坐标：(x, y)
 * @param x {number} x 的值
 * @return {number} y 的值
 */
function twoPointLine(point1, point2, x) {
    let right = (x - point2.x) / (point1.x - point2.x);
    return right * (point1.y - point2.y) + point2.y;
}